package com.siashan.unipay4j.wx.pay;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.siashan.unipay4j.core.IPayConfig;
import com.siashan.unipay4j.core.Result;
import com.siashan.unipay4j.core.pay.PayModel;
import com.siashan.unipay4j.wx.model.UnifiedOrderModel;
import com.siashan.unipay4j.wx.sdk.WXPayConstants;
import com.siashan.unipay4j.wx.sdk.WXPayUtil;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Signer;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.Map;

/**
 * 微信APP支付
 *
 * @author siashan
 * @since v1.0.1
 **/
@Slf4j
public class WxPayApp extends WxPay {

    public WxPayApp() {
        super();
    }

    public WxPayApp(IPayConfig payConfig) {
        super(payConfig);
    }



    @Override
    public String loadV3PayUrl() {
        return WXPayConstants.V3_PAY_URL_APP;
    }

    /**
     * 支付
     *
     * @param model  支付请求参数
     * @return 支付结果
     */
    @Override
    public Result pay(PayModel model) {
        return doPay(model, WxTradeTypeEnum.APP);
    }

    /**
     * 是否需要openId参数
     *
     * @return  是否需要
     */
    @Override
    public boolean needOpenId() {
        return false;
    }


    /**
     * 处理交易成功逻辑
     *
     * @param r  报文
     * @return   返回结果
     * @throws Exception
     */
    @Override
    public Result doTradeSuccess(Map<String, String> r) throws Exception {
        Map<String, String> map = new HashMap<>();
        map.put("appid", r.get("appid"));
        map.put("partnerid", wxPayConfig.getMchId());
        map.put("prepayid", r.get("prepay_id"));
        map.put("package", "Sign=WXPay");
        map.put("timeStamp", WXPayUtil.getCurrentTimestamp() + "");
        map.put("nonceStr", WXPayUtil.generateNonceStr());
        map.put("sign", WXPayUtil.generateSignature(map, wxPayConfig.getKey(), wxPayConfig.getSignType()));
        return Result.tradeSuccess(map);
    }

    /**
     * 处理交易成功逻辑
     *
     * @param body  报文
     * @param orderModel 下单参数
     * @return 返回结果
     */
    @Override
    public Result doTradeSuccessV3(String body, UnifiedOrderModel orderModel)  {
        JSONObject bodyJson = JSON.parseObject(body);
        String prepayId = bodyJson.getString("prepay_id").trim();
        String appId = orderModel.getAppid();
        String timeStamp = WXPayUtil.getCurrentTimestamp() + "";
        String nonceStr = WXPayUtil.generateNonceStr();

        byte[] bytes = WXPayUtil.genV3SignRawStr(appId, timeStamp, nonceStr, prepayId);

        PrivateKeySigner signer = new PrivateKeySigner(wxPayConfig.getMerchantSerialNumber(),loadPrivateKey());
        Signer.SignatureResult signResult = signer.sign(bytes);
        Map<String, String> map = new HashMap<>();
        map.put("appid", appId);
        map.put("partnerid", wxPayConfig.getMchId());
        map.put("prepayid", prepayId);
        map.put("package", "Sign=WXPay");
        map.put("timeStamp", timeStamp);
        map.put("nonceStr", nonceStr);
        map.put("sign", signResult.getSign());
        return Result.tradeSuccess(map);
    }
}
